#!/usr/bin/env python3
"""
LightDM 自动登录脚本（修复键盘模拟问题）
需要安装: python3, python3-xlib, xdotool, pynput
sudo apt install python3 python3-xlib xdotool
pip install pynput
"""

import time
import subprocess
import threading
from pynput import keyboard
from Xlib import X, display
from Xlib.ext.xtest import fake_input
from Xlib import XK

# 配置参数
PASSWORD = "root"  # 替换为实际密码
HOTKEY = "<ctrl>+a"  # 使用 Ctrl+A 作为快捷键
DEBUG = True  # 调试模式，显示更多信息

def log(message):
    """日志记录函数"""
    if DEBUG:
        print(f"[LOG] {message}")

def find_lightdm_window():
    """查找 LightDM 登录窗口"""
    try:
        d = display.Display()
        root = d.screen().root
        
        # 获取所有窗口
        windows = root.query_tree().children
        
        for win in windows:
            try:
                # 获取窗口名称
                name = win.get_wm_name()
                if name and "mate-screensaver" in name.lower():
                    log(f"找到 LightDM 窗口: {name}")
                    return win
            except:
                continue
        
        log("未找到 LightDM 窗口")
        return None
    except Exception as e:
        log(f"查找窗口时出错: {str(e)}")
        return None

def type_password(password):
    """使用 xdotool 输入密码"""
    try:
        log("开始输入密码...")
        subprocess.run(["xdotool", "type", "--delay", "50", password])
        time.sleep(0.5)
        subprocess.run(["xdotool", "key", "Return"])
        log("密码输入完成")
        return True
    except Exception as e:
        log(f"输入密码时出错: {str(e)}")
        return False

def simulate_keyboard(password):
    """使用 Xlib 模拟键盘输入（修复版）"""
    try:
        log("开始模拟键盘输入...")
        d = display.Display()
        
        for char in password:
            # 获取字符的键码
            keycode = d.keysym_to_keycode(ord(char))
            fake_input(d, X.KeyPress, keycode)
            fake_input(d, X.KeyRelease, keycode)
            d.sync()
            time.sleep(0.05)
        
        # 模拟回车键 - 修复：使用正确的常量
        # enter_keycode = d.keysym_to_keycode(XK_return)
        enter_keycode = 36

        fake_input(d, X.KeyPress, enter_keycode)
        fake_input(d, X.KeyRelease, enter_keycode)
        d.sync()
        log("键盘模拟完成")
        return True
    except Exception as e:
        log(f"模拟键盘时出错: {str(e)}")
        return False

def activate_lightdm_window():
    """激活 LightDM 窗口"""
    try:
        lightdm_win = find_lightdm_window()
        if not lightdm_win:
            log("无法激活窗口：未找到 LightDM")
            return False
        
        # 激活窗口
        lightdm_win.set_input_focus(X.RevertToParent, X.CurrentTime)
        lightdm_win.configure(stack_mode=X.Above)
        display.Display().sync()
        
        log("LightDM 窗口已激活")
        time.sleep(1)  # 等待窗口激活
        return True
    except Exception as e:
        log(f"激活窗口时出错: {str(e)}")
        return False

def perform_login():
    """执行登录操作"""
    if not activate_lightdm_window():
        log("登录失败：无法激活窗口")
        return False
    
    # 选择输入方法
    # return type_password(PASSWORD)  # 方法1: 使用 xdotool
    return simulate_keyboard(PASSWORD)  # 方法2: 使用 Xlib 模拟

def on_hotkey_press():
    """快捷键按下时的回调函数"""
    log(f"检测到快捷键按下，开始登录过程...")
    threading.Thread(target=perform_login).start()

def start_hotkey_listener():
    """启动快捷键监听器"""
    log(f"启动快捷键监听器，使用 {HOTKEY} 触发登录")
    
    # 创建全局热键
    with keyboard.GlobalHotKeys({
        HOTKEY: on_hotkey_press
    }) as listener:
        listener.join()

def main():
    log("LightDM 自动登录程序已启动")
    log(f"配置密码: {PASSWORD}")
    log(f"触发快捷键: {HOTKEY}")
    
    # 启动快捷键监听器
    start_hotkey_listener()

if __name__ == "__main__":
    main()
